/*!
 * \file WtTWapExeUnit.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 *
 * \brief TWAP执行单元
 * \details 实现时间加权平均价格(TWAP)执行算法，在指定时间内均匀分布订单
 */
#pragma once
#include "WtOrdMon.h"
#include "../Includes/ExecuteDefs.h"
#include "../Share/StdUtils.hpp"

USING_NS_WTP;

/**
 * @class WtTWapExeUnit
 * @brief TWAP执行单元类
 * @details 继承自ExecuteUnit，实现时间加权平均价格(TWAP)执行算法
 *          在指定的时间窗口内将大单分解为多个小单，均匀分布执行
 *          支持多种价格模式和执行策略参数配置
 */
class WtTWapExeUnit : public ExecuteUnit
{
public:
	/**
	 * @brief 构造函数
	 */
	WtTWapExeUnit();
	
	/**
	 * @brief 析构函数
	 */
	virtual ~WtTWapExeUnit();

private:
	/**
	 * @brief 执行计算逻辑
	 * @details 根据TWAP算法计算当前应该执行的数量和价格
	 */
	void	do_calc();
	
	/**
	 * @brief 立即执行指定数量
	 * @param qty 要执行的数量
	 */
	void	fire_at_once(double qty);

public:
	/**
	 * @brief 获取执行工厂名称
	 * @return 返回所属执行工厂的名称
	 */
	virtual const char* getFactName() override;

	/**
	 * @brief 获取执行单元名称
	 * @return 返回执行单元的名称
	 */
	virtual const char* getName() override;

	/**
	 * @brief 初始化执行单元
	 * @param ctx 执行单元上下文环境
	 * @param stdCode 标准化的合约代码
	 * @param cfg 配置参数
	 */
	virtual void init(ExecuteContext* ctx, const char* stdCode, WTSVariant* cfg) override;

	/**
	 * @brief 订单回报处理
	 * @param localid 本地订单号
	 * @param stdCode 合约代码
	 * @param isBuy 买入或卖出标志
	 * @param leftover 剩余数量
	 * @param price 委托价格
	 * @param isCanceled 是否已撤销
	 */
	virtual void on_order(uint32_t localid, const char* stdCode, bool isBuy, double leftover, double price, bool isCanceled) override;

	/**
	 * @brief tick数据回调处理
	 * @param newTick 最新的tick数据
	 */
	virtual void on_tick(WTSTickData* newTick) override;

	/**
	 * @brief 成交回报处理
	 * @param localid 本地订单号
	 * @param stdCode 合约代码
	 * @param isBuy 买入或卖出标志
	 * @param vol 成交数量，这里没有正负，通过isBuy确定是买入还是卖出
	 * @param price 成交价格
	 */
	virtual void on_trade(uint32_t localid, const char* stdCode, bool isBuy, double vol, double price) override;

	/**
	 * @brief 新订单委托回报处理
	 * @param localid 本地订单号
	 * @param stdCode 合约代码
	 * @param bSuccess 委托是否成功
	 * @param message 回报消息
	 */
	virtual void on_entrust(uint32_t localid, const char* stdCode, bool bSuccess, const char* message) override;

	/**
	 * @brief 设置新的目标仓位
	 * @param stdCode 合约代码
	 * @param newVol 新的目标仓位
	 */
	virtual void set_position(const char* stdCode, double newVol) override;

	/**
	 * @brief 交易通道就绪回调
	 */
	virtual void on_channel_ready() override;

	/**
	 * @brief 交易通道丢失回调
	 */
	virtual void on_channel_lost() override;


private:
	WTSTickData* _last_tick;	///< 最后一笔行情数据
	double		_target_pos;	///< 目标仓位
	bool		_channel_ready;	///< 交易通道是否就绪


	WTSCommodityInfo*	_comm_info;	///< 品种信息

	//////////////////////////////////////////////////////////////////////////
	// 执行参数
	WtOrdMon		_orders_mon;	///< 订单监控器
	uint32_t		_cancel_cnt;	///< 撤单次数统计

	//////////////////////////////////////////////////////////////////////////
	// 配置参数
	uint32_t		_total_secs;	///< 执行总时长，单位秒
	uint32_t		_total_times;	///< 总执行次数
	uint32_t		_tail_secs;		///< 执行尾部时长
	uint32_t		_ord_sticky;	///< 挂单时长，单位秒
	uint32_t		_price_mode;	///< 价格模式: 0-最新价，1-对手价，2-排队价
	uint32_t		_price_offset;	///< 挂单价格偏移，正数表示价格偏移，负数表示负偏移

	//////////////////////////////////////////////////////////////////////////
	// 运行时状态
	double			_this_target;	///< 当前目标仓位
	uint32_t		_fire_span;		///< 执行间隔
	uint32_t		_fired_times;	///< 已执行次数
	uint64_t		_last_fire_time;	///< 最后执行时间
};

